#include <stdio.h>
#include <stdlib.h>
struct usinglelist {
    struct usinglenode* header;
    struct usinglenode* tailer;
};

struct usinglenode {
    struct usinglenode* next;
};

#define SLIST_ADD(plist, pnode)                                         \
    do {                                                                \
        (pnode)->next = (plist)->header;                                \
        (plist)->header = pnode;                                        \
        (plist)->tailer = NULL==(plist)->tailer?pnode:(plist)->tailer;  \
    }while(0);


#define SLIST_ADD_TAILER(plist, pnode)                                  \
    do {                                                                \
        if(NULL==(plist)->header) {(plist)->header=(pnode);}            \
        else  {(plist)->tailer->next=(pnode); }                         \
        (plist)->tailer = (pnode);                                      \
        (pnode)->next = NULL;                                           \
    }while(0)




#define __OFFSETOF(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define SLIST_ENTRY(snode, type, member) (type*)((void*)snode-(void*)&(((type*)0)->member))
#define SLIST_FOREACH_SNODE(plist, snode) for(snode=(plist)->header; NULL!=snode; snode=snode->next)

#define SLIST_FOREACH(plist, node, type, member) \
for( node=(type*)((void*)(plist)->header-__OFFSETOF(type, member)); \
        NULL!=(void*)node+__OFFSETOF(type, member);    \
        node = (type*)((void*)(((struct usinglenode*)((void*)node+__OFFSETOF(type, member)))->next)-__OFFSETOF(type, member))) 


#define slist_delete1(plist, snode_prev, snode, node, type, member, pattern, num)    \
for( node=(type*)((void*)(plist)->header-__OFFSETOF(type, member)); \
        /*NULL!=(void*)node+__OFFSETOF(type, member)*/;    \
        node = (type*)((void*)(((struct usinglenode*)((void*)node+__OFFSETOF(type, member)))->next)-__OFFSETOF(type, member))) {\
    printf("node_delete = %p\n", node);\
    if(NULL==(void*)node+__OFFSETOF(type, member)) {break;}\
    if(!(pattern)) {\
        pnode_prev = NULL==pnode_prev?(struct usinglenode*)((void*)node+__OFFSETOF(type, member)):pnode_prev->next;\
        node = (type*)((void*)(((struct usinglenode*)((void*)node+__OFFSETOF(type, member)))->next)-__OFFSETOF(type, member))\
        continue;\
    }\
    (num) ++;\
    /*printf("pnode_prev=%p\n", pnode_prev);*/  \
    if(NULL == pnode_prev) {/* header. */\
        (plist)->header = (plist)->header->next;\
        if(NULL == (plist)->header) {\
            (plist)->tailer = NULL;\
        }\
    }\
    else if(NULL == pnode_prev->next->next) {/* tailer. */\
        pnode_prev->next = NULL;\
        (plist)->tailer = pnode_prev;\
    }\
    else {\
        pnode_prev->next = pnode_prev->next->next;\
    }\


#define slist_delete_begin(plist, node, type, member, pattern, num) \
do {\
struct usinglenode* s1node_prev_fjsfussfdjfs= NULL;\
struct usinglenode* snode_fjskdfsillfs= NULL;\
for(snode_fjskdfsillfs=(plist)->header; NULL!=snode_fjskdfsillfs; ) {\
    node=SLIST_ENTRY(snode_fjskdfsillfs, type, member);\
    if(!(pattern)) {\
        s1node_prev_fjsfussfdjfs = snode_fjskdfsillfs;\
        snode_fjskdfsillfs = snode_fjskdfsillfs->next;\
        continue;\
    }\
    if(NULL == s1node_prev_fjsfussfdjfs) {\
        (plist)->header = (plist)->header->next;\
        if(NULL == (plist)->header) {\
            (plist)->tailer = NULL;\
        }\
    }\
    else if(NULL == snode_fjskdfsillfs->next) {/* tailer. */\
        (plist)->tailer = s1node_prev_fjsfussfdjfs;\
        (plist)->tailer->next = NULL;\
    }\
    else {\
        s1node_prev_fjsfussfdjfs->next = snode_fjskdfsillfs->next;\
    }\
    snode_fjskdfsillfs = snode_fjskdfsillfs->next;

    

#define slist_delete_end }}while(0);





#if 0

#endif









struct nodes {
    struct usinglelist list;
};


struct node {
    struct usinglenode snode;
    int v;
};


int test()
{
    struct nodes nodes;
    nodes.list.header = nodes.list.tailer = NULL;

    int i;
    for(i=0; i<10; i++) {
        struct node* node = malloc(sizeof(*node));
        node->v = i;
        printf("%p[%2d] ", node, node->v);
        SLIST_ADD_TAILER(&nodes.list, &node->snode);
    }
    printf("\n");

    struct usinglenode* snode;
    struct node* node = NULL;
    SLIST_FOREACH_SNODE(&nodes.list, snode) {
        printf("%p ", snode);
    }
    printf("\n");

    SLIST_FOREACH_SNODE(&nodes.list, snode) {
        node = SLIST_ENTRY(snode, struct node, snode);
        printf("%p ", node);
    }
    printf("\n");

    SLIST_FOREACH(&nodes.list, node, struct node, snode) {
        printf("%p ", node);
    }
    printf("\n");

    printf("====== delete\n");
    struct node* node_delete;
    int num = 0;

    printf("====== delete 0\n");
    num = 0;
    slist_delete_begin(&nodes.list, node_delete, struct node, snode, node_delete->v==0, num)
        printf("free %p\n", node_delete);free(node_delete);
        printf("%p %p ", nodes.list.header, nodes.list.tailer);
        SLIST_FOREACH(&nodes.list, node, struct node, snode) {
            printf("%02d ", node->v);
        }
        printf("\n");

    slist_delete_end

    printf("====== delete 3\n");
    num = 0;
    slist_delete_begin(&nodes.list, node_delete, struct node, snode, node_delete->v==3, num)
        printf("free %p\n", node_delete);free(node_delete);
        printf("%p %p ", nodes.list.header, nodes.list.tailer);
        SLIST_FOREACH(&nodes.list, node, struct node, snode) {
            printf("%02d ", node->v);
        }
        printf("\n");

    slist_delete_end

    printf("====== delete 1..6\n");
    num = 0;
    slist_delete_begin(&nodes.list, node_delete, struct node, snode, node_delete->v>=1&&node_delete->v<=6, num)
        printf("free %p\n", node_delete);free(node_delete);
        printf("%p %p ", nodes.list.header, nodes.list.tailer);
        SLIST_FOREACH(&nodes.list, node, struct node, snode) {
            printf("%02d ", node->v);
        }
        printf("\n");

    slist_delete_end

    printf("====== delete 9\n");
    num = 0;
    slist_delete_begin(&nodes.list, node_delete, struct node, snode, node_delete->v==9, num)
        printf("free %p\n", node_delete);free(node_delete);
        printf("%p %p ", nodes.list.header, nodes.list.tailer);
        SLIST_FOREACH(&nodes.list, node, struct node, snode) {
            printf("%02d ", node->v);
        }
        printf("\n");

    slist_delete_end

    printf("====== delete 8\n");
    num = 0;
    slist_delete_begin(&nodes.list, node_delete, struct node, snode, node_delete->v==8, num)
        printf("free %p\n", node_delete);free(node_delete);
        printf("%p %p ", nodes.list.header, nodes.list.tailer);
        SLIST_FOREACH(&nodes.list, node, struct node, snode) {
            printf("%02d ", node->v);
        }
        printf("\n");

    slist_delete_end

    printf("====== delete all\n");
    num = 0;
    slist_delete_begin(&nodes.list, node_delete, struct node, snode, 1, num)
        printf("free %p\n", node_delete);free(node_delete);
        printf("%p %p ", nodes.list.header, nodes.list.tailer);
        SLIST_FOREACH(&nodes.list, node, struct node, snode) {
            printf("%02d ", node->v);
        }
        printf("\n");

    slist_delete_end

    for(i=0; i<10; i++) {
        struct node* node = malloc(sizeof(*node));
        node->v = i;
        printf("%p[%2d] ", node, node->v);
        SLIST_ADD(&nodes.list, &node->snode);
    }
    printf("\n");

    printf("====== delete 7..9\n");
    num = 0;
    slist_delete_begin(&nodes.list, node_delete, struct node, snode, 
            node_delete->v>=7&&node_delete->v<=9, num)
        printf("free %p\n", node_delete);free(node_delete);
        printf("%p %p ", nodes.list.header, nodes.list.tailer);
        SLIST_FOREACH(&nodes.list, node, struct node, snode) {
            printf("%02d ", node->v);
        }
        printf("\n");

    slist_delete_end

    printf("====== delete 0..2\n");
    num = 0;
    slist_delete_begin(&nodes.list, node_delete, struct node, snode, 
            node_delete->v>=0&&node_delete->v<=2, num)
        printf("free %p\n", node_delete);free(node_delete);
        printf("%p %p ", nodes.list.header, nodes.list.tailer);
        SLIST_FOREACH(&nodes.list, node, struct node, snode) {
            printf("%02d ", node->v);
        }
        printf("\n");

    slist_delete_end

    printf("====== delete 3..6\n");
    num = 0;
    slist_delete_begin(&nodes.list, node_delete, struct node, snode, 
            node_delete->v>=3&&node_delete->v<=6, num)
        printf("free %p\n", node_delete);free(node_delete);
        printf("%p %p ", nodes.list.header, nodes.list.tailer);
        SLIST_FOREACH(&nodes.list, node, struct node, snode) {
            printf("%02d ", node->v);
        }
        printf("\n");

    slist_delete_end

    return 0;
}


int main()
{
    while(1) {
        test();
    }
    return 0;
}
